<template>
	<div class="credential-form-container">
		<el-dialog :title="state.dialog.title" v-model="state.dialog.isShowDialog" width="800px" @close="onCancel">
			<el-form ref="credentialFormRef" :model="state.ruleForm" :rules="state.rules" size="default" label-width="120px">
				<el-row :gutter="35">
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
						<el-form-item label="凭证ID" prop="credentialId">
							<el-input
								v-model="state.ruleForm.credentialId"
								placeholder="请输入凭证ID"
								clearable
								:disabled="state.dialog.type === 'edit'"
							></el-input>
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
						<el-form-item label="凭证类型" prop="type">
							<el-select v-model="state.ruleForm.type" placeholder="请选择凭证类型" class="w100" @change="onTypeChange">
								<el-option label="用户名密码" value="usernamePassword"></el-option>
								<el-option label="SSH密钥" value="sshKey"></el-option>
								<el-option label="密钥文本" value="secretText"></el-option>
								<el-option label="证书" value="certificate"></el-option>
							</el-select>
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
						<el-form-item label="作用域" prop="scope">
							<el-select v-model="state.ruleForm.scope" placeholder="请选择作用域" class="w100">
								<el-option label="全局" value="GLOBAL"></el-option>
								<el-option label="系统" value="SYSTEM"></el-option>
							</el-select>
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
						<el-form-item label="描述" prop="description">
							<el-input
								v-model="state.ruleForm.description"
								type="textarea"
								placeholder="请输入凭证描述"
								maxlength="200"
								show-word-limit
								:rows="3"
							></el-input>
						</el-form-item>
					</el-col>

					<!-- 用户名密码类型 -->
					<template v-if="state.ruleForm.type === 'usernamePassword'">
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
							<el-form-item label="用户名" prop="username">
								<el-input v-model="state.ruleForm.username" placeholder="请输入用户名" clearable></el-input>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
							<el-form-item label="密码" prop="password">
								<el-input
									v-model="state.ruleForm.password"
									type="password"
									placeholder="请输入密码"
									show-password
									clearable
								></el-input>
							</el-form-item>
						</el-col>
					</template>

					<!-- SSH密钥类型 -->
					<template v-if="state.ruleForm.type === 'sshKey'">
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
							<el-form-item label="用户名" prop="username">
								<el-input v-model="state.ruleForm.username" placeholder="请输入用户名" clearable></el-input>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
							<el-form-item label="密码短语">
								<el-input
									v-model="state.ruleForm.passphrase"
									type="password"
									placeholder="请输入密码短语（可选）"
									show-password
									clearable
								></el-input>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
							<el-form-item label="私钥" prop="privateKey">
								<el-input
									v-model="state.ruleForm.privateKey"
									type="textarea"
									placeholder="请输入SSH私钥内容"
									:rows="8"
								></el-input>
							</el-form-item>
						</el-col>
					</template>

					<!-- 密钥文本类型 -->
					<template v-if="state.ruleForm.type === 'secretText'">
						<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
							<el-form-item label="密钥文本" prop="secretText">
								<el-input
									v-model="state.ruleForm.secretText"
									type="textarea"
									placeholder="请输入密钥文本内容"
									:rows="6"
								></el-input>
							</el-form-item>
						</el-col>
					</template>

					<!-- 证书类型 -->
					<template v-if="state.ruleForm.type === 'certificate'">
						<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
							<el-form-item label="证书内容" prop="certificate">
								<el-input
									v-model="state.ruleForm.certificate"
									type="textarea"
									placeholder="请输入证书内容"
									:rows="8"
								></el-input>
							</el-form-item>
						</el-col>
					</template>
				</el-row>
			</el-form>
			<template #footer>
				<span class="dialog-footer">
					<el-button @click="onCancel" size="default">取 消</el-button>
					<el-button type="primary" @click="onSubmit" size="default" :loading="state.loading">
						{{ state.dialog.submitTxt }}
					</el-button>
				</span>
			</template>
		</el-dialog>
	</div>
</template>

<script setup lang="ts" name="credentialForm">
import { reactive, ref } from 'vue';
import { ElMessage } from 'element-plus';
import { credentialApi, type CredentialItem, type CredentialFormData } from '/@/api/jenkins/credential';

// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh']);

// 定义变量内容
const credentialFormRef = ref();
const state = reactive<{
	ruleForm: CredentialFormData;
	rules: any;
	dialog: {
		isShowDialog: boolean;
		type: string;
		title: string;
		submitTxt: string;
	};
	loading: boolean;
}>({
	ruleForm: {
		credentialId: '',
		description: '',
		type: 'usernamePassword',
		username: '',
		password: '',
		privateKey: '',
		passphrase: '',
		secretText: '',
		certificate: '',
		scope: 'GLOBAL',
	},
	rules: {
		credentialId: [{ required: true, message: '请输入凭证ID', trigger: 'blur' }],
		description: [{ required: true, message: '请输入描述', trigger: 'blur' }],
		type: [{ required: true, message: '请选择凭证类型', trigger: 'change' }],
		scope: [{ required: true, message: '请选择作用域', trigger: 'change' }],
		username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
		password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
		privateKey: [{ required: true, message: '请输入私钥', trigger: 'blur' }],
		secretText: [{ required: true, message: '请输入密钥文本', trigger: 'blur' }],
		certificate: [{ required: true, message: '请输入证书内容', trigger: 'blur' }],
	},
	dialog: {
		isShowDialog: false,
		type: '',
		title: '',
		submitTxt: '',
	},
	loading: false,
});

// 打开弹窗
const openDialog = (type: string, row?: CredentialItem) => {
	cleanForm();
	state.dialog.type = type;
	if (type === 'edit') {
		state.dialog.title = '编辑凭证';
		state.dialog.submitTxt = '修 改';
		// 编辑时填充表单数据
		if (row) {
			state.ruleForm.id = row.id;
			state.ruleForm.credentialId = row.credentialId;
			state.ruleForm.description = row.description;
			state.ruleForm.type = row.type;
			state.ruleForm.username = row.username || '';
			state.ruleForm.scope = row.scope;
			// 敏感信息不回填，需要重新输入
		}
	} else {
		state.dialog.title = '新增凭证';
		state.dialog.submitTxt = '新 增';
	}
	state.dialog.isShowDialog = true;
};

// 关闭弹窗
const closeDialog = () => {
	state.dialog.isShowDialog = false;
};

// 取消
const onCancel = () => {
	closeDialog();
};

// 清空表单
const cleanForm = () => {
	state.ruleForm = {
		credentialId: '',
		description: '',
		type: 'usernamePassword',
		username: '',
		password: '',
		privateKey: '',
		passphrase: '',
		secretText: '',
		certificate: '',
		scope: 'GLOBAL',
	};
};

// 凭证类型改变时清空相关字段
const onTypeChange = () => {
	state.ruleForm.username = '';
	state.ruleForm.password = '';
	state.ruleForm.privateKey = '';
	state.ruleForm.passphrase = '';
	state.ruleForm.secretText = '';
	state.ruleForm.certificate = '';
};

// 提交
const onSubmit = () => {
	credentialFormRef.value.validate((valid: boolean) => {
		if (!valid) return;

		// 根据凭证类型验证必填字段
		if (!validateByType()) return;

		state.loading = true;
		const api = state.dialog.type === 'edit' ? credentialApi().updateCredential : credentialApi().createCredential;

		api(state.ruleForm)
			.then(() => {
				ElMessage.success(state.dialog.type === 'edit' ? '修改成功' : '新增成功');
				closeDialog();
				emit('refresh');
			})
			.catch(() => {
				// 错误处理由拦截器统一处理
			})
			.finally(() => {
				state.loading = false;
			});
	});
};

// 根据凭证类型验证
const validateByType = () => {
	const { type, username, password, privateKey, secretText, certificate } = state.ruleForm;

	switch (type) {
		case 'usernamePassword':
			if (!username) {
				ElMessage.error('请输入用户名');
				return false;
			}
			if (!password) {
				ElMessage.error('请输入密码');
				return false;
			}
			break;
		case 'sshKey':
			if (!username) {
				ElMessage.error('请输入用户名');
				return false;
			}
			if (!privateKey) {
				ElMessage.error('请输入私钥');
				return false;
			}
			break;
		case 'secretText':
			if (!secretText) {
				ElMessage.error('请输入密钥文本');
				return false;
			}
			break;
		case 'certificate':
			if (!certificate) {
				ElMessage.error('请输入证书内容');
				return false;
			}
			break;
	}
	return true;
};

// 暴露变量
defineExpose({
	openDialog,
});
</script>

<style scoped lang="scss">
.credential-form-container {
	.w100 {
		width: 100%;
	}
}
</style>